package com.ssm.server.util;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

/**
 * @ClassName: TokenUtil
 * @Description: 验证客户端的token
 */
public class Token2Util
{
    
    private static String SUFFIX = "sjs";
    
    private static String token = "token";
    
    private static Logger LOG = Logger.getLogger ( Token2Util.class );
    
    /**
     * @Title: validateToken
     * @Description: 判断客户端和服务端的令牌是否一致
     * @param @param request
     * @param @return
     * @return boolean 返回类型
     * @throws
     */
    public static boolean validateToken ( HttpServletRequest request )
    {
        
        String clientToken = request.getParameter ( token );
        String timeStamp = request.getParameter ( "timeStamp" );
        // String key = request.getParameter("key");
        // System.out.println("client key--->>>" + clientToken);
        String serverToken = token ( request , timeStamp );
        return serverToken.equals ( clientToken );
    }
    
    public static boolean sqlValidate ( HttpServletRequest request )
    {
        
        StringBuffer buff=request.getRequestURL ( );
        LOG.info(buff.toString ( ));
        Enumeration < String > params = request.getParameterNames ( );
        String sql = "";
        while ( params.hasMoreElements ( ) )
        {
            // 得到参数名
            String name = params.nextElement ( ).toString ( );
            LOG.info ( "name===========================" + name + "--" );
            if(null!=name && (buff.toString ( ).contains ("/IPO/add.do")||name.toLowerCase().contains ( "value" )||name.toLowerCase().contains ( "param" )||name.toLowerCase().contains ( "usertel" )||name.toLowerCase().contains ( "channel" )||name.toLowerCase().contains ( "brokerno" )||name.toLowerCase().contains ( "password" )||name.toLowerCase().contains ( "currencyType" )||name.toLowerCase().contains ( "currencyPair" )||name.toLowerCase().contains ( "code" )||name.toLowerCase().contains ( "key" )||name.toLowerCase().contains ( "token" )||name.toLowerCase().contains ( "openid" )||name.toLowerCase().contains ( "from" )||name.toLowerCase().contains ( "url" )||name.toLowerCase().contains ( "platform" )||name.toLowerCase().contains ( "uuid" )||name.toLowerCase().contains ( "userid" )||name.toLowerCase().contains ( "type" )||name.toLowerCase().contains ( "email" )||name.toLowerCase().contains ( "bank" )||name.toLowerCase().contains ( "content" )||buff.toString ( ).contains("sjs_alipay_return_url")||buff.toString ( ).contains ("sjs_alipay_notify_url")||buff.toString ( ).contains ("InvestorsEvaluate.do")||buff.toString ( ).contains ("/sinaNotify.do")||buff.toString ( ).contains ("/sianpay_message.html")||buff.toString ( ).contains ("/RSRRecharge.do")||buff.toString ( ).contains ("/wxRedictUrl.do")||buff.toString ( ).contains ("/rsrFinish.do")||buff.toString ( ).contains ("unionpay/finish.do")||buff.toString ( ).contains("validateUnionSign.do"))){
                
                continue;
            }
            // 得到参数对应值
            String [ ] value = request.getParameterValues ( name );
            
            if ( null != value && value.length > 0 )
            {
                
                for ( String string : value )
                {
                    sql = sql + string + ",";
                }
            }
            
        }
        LOG.info ( "============================SQL" + sql );
        
        if ( null != sql && ! "".equals ( sql ) )
        {
            
            sql = sql.toLowerCase ( );// 统一转为小写
            
            String badStr = "and,exec,execute,insert,create,drop,table,from,grant,use,group_concat,column_name," +
                        
                        "information_schema.columns,script,table_schema,union,where,select,delete,update,order,by,count,*," +
                        
                        "chr,mid,master,truncate,char,declare,or,+||,like,//,%,#,'";// 过滤掉的sql关键字，可以手动添加
            
            String [ ] badStrs = badStr.split ( "," );
            
            for ( String string : badStrs )
            {
                String [ ] str3 = sql.split ( "," );
                
                if ( null != str3 && ! "".equals ( str3 ) )
                {
                    
                    for ( String string2 : str3 )
                    {
                        if ( string2.contains ( string ) )
                        {
                            
                            return true;
                        }
                    }
                }
            }
        }
        return false;
        
    }
    
    public static boolean sqlValidateNew ( HttpServletRequest request )
    {
        
        StringBuffer buff=request.getRequestURL ( );
        LOG.info(buff.toString ( ));
        Enumeration < String > params = request.getParameterNames ( );
        String sql = "";
        while ( params.hasMoreElements ( ) )
        {
            // 得到参数名
            String name = params.nextElement ( ).toString ( );
            LOG.info ( "name===========================" + name + "--" );
            if(null!=name && (name.toLowerCase().contains ( "headimgurl" )||name.toLowerCase().contains ( "value" )||name.toLowerCase().contains ( "bank" )||name.toLowerCase().contains ( "from" )||name.toLowerCase().contains ( "usertel" )||name.toLowerCase().contains ( "brokerno" )||name.toLowerCase().contains ( "channel" )||name.toLowerCase().contains ( "password" )||name.toLowerCase().contains ( "verycode" )||name.toLowerCase().contains ( "token" )||name.toLowerCase().contains ( "openid" )||name.toLowerCase().contains ( "appkey" )||name.toLowerCase().contains ( "url" )||name.toLowerCase().contains ( "platform" )||name.toLowerCase().contains ( "uuid" )||name.toLowerCase().contains ( "userid" )||name.toLowerCase().contains ( "type" )||name.toLowerCase().contains ( "email" )||name.toLowerCase().contains ( "content" )||name.toLowerCase().contains ( "sharecode" )||buff.toString ( ).contains("bookingEvaluate.do")||buff.toString ( ).contains ("InvestorsEvaluate.do")||buff.toString ( ).contains ("/sinaNotify.do")||buff.toString ( ).contains ("/sianpay_message.html")||buff.toString ( ).contains ("/RSRRecharge.do")||buff.toString ( ).contains ("/wxRedictUrl.do")||buff.toString ( ).contains ("/rsrFinish.do")||buff.toString ( ).equals ("unionpay/finish.do")||buff.toString ( ).contains("validateUnionSign.do"))){
                
                continue;
            }
            // 得到参数对应值
            String [ ] value = request.getParameterValues ( name );
            
            if ( null != value && value.length > 0 )
            {
                
                for ( String string : value )
                {
                    sql = sql + string + ",";
                }
            }
            
        }
        LOG.info ( "============================SQL" + sql );
        
        if ( null != sql && ! "".equals ( sql ) )
        {
            
            sql = sql.toLowerCase ( );// 统一转为小写
            
            String badStr = "and,exec,execute,insert,create,drop,table,from,grant,use ,group_concat,column_name," +
                        
                        "information_schema.columns,script,table_schema,union,where,select,delete,update,order,by ,count,*," +
                        
                        "chr ,mid ,master,truncate,char,declare,or ,+||,like,//,%,#,'";// 过滤掉的sql关键字，可以手动添加
            
            String [ ] badStrs = badStr.split ( "," );
            
            for ( String string : badStrs )
            {
                String [ ] str3 = sql.split ( "," );
                
                if ( null != str3 && ! "".equals ( str3 ) )
                {
                    
                    for ( String string2 : str3 )
                    {
                        if ( string2.contains ( string ) )
                        {
                            
                            return true;
                        }
                    }
                }
            }
        }
        return false;
        
    }
    
    /**
     * @Title: token
     * @Description: 获取到服务端的令牌
     * @param @param request
     * @param @return
     * @return String 返回类型
     * @throws
     */
    private static String token ( HttpServletRequest request , String timeStamp )
    {
        
        String path = request.getServletPath ( );
        path = path.replace ( "/" , "" );
        path = path.replace ( ".do" , "" );
        path = path.substring ( path.length ( ) - 3 );
        String parameters = getParameters ( request );
        String initToken = path + parameters + SUFFIX;
        StringBuilder result = new StringBuilder ( );
        // System.out.println("server key--->>>" + initToken);
        System.err.println ( "第一次MD5" + initToken );
        initToken = MD5.MD5Encode ( initToken );
        System.err.println ( "第一次MD5结束" + initToken );
        if ( null != initToken && ! "".equals ( initToken ) && initToken.length ( ) > 15 )
        {
            
            result.append ( initToken.substring ( 0 , 3 ) + initToken.substring ( 8 , 9 ) + initToken.substring ( 10 , 11 )
                        + initToken.substring ( 14 , 15 ) );
            
            System.err.println ( "抽取出来的值" + result.toString ( ) );
            
            if ( null != timeStamp && ! "".equals ( timeStamp ) )
            {
                
                timeStamp = timeStamp.substring ( timeStamp.length ( ) - 3 );
                
                System.err.println ( "时间戳后三位" + timeStamp );
                result.append ( timeStamp );
            }
            
        }
        System.err.println ( "第二次MD5" + initToken + result.toString ( ) );
        System.err.println ( "第二次MD5" + MD5.MD5Encode ( initToken + result.toString ( ) ) );
        return MD5.MD5Encode ( initToken + result.toString ( ) );
    }
    
    /**
     * @Title: getParameters
     * @Description: 获取到请求的参数
     * @param @param request
     * @param @return
     * @return String 返回类型
     * @throws
     */
    private static String getParameters ( HttpServletRequest request )
    {
        
        Map < String , String [ ] > parameterMap = request.getParameterMap ( );
        // for (Entry<String, String[]> entry : parameterMap.entrySet()) {
        // System.out.println(entry.getKey() + "---->>>>"
        // + entry.getValue()[0]);
        // }
        
        StringBuilder builder = new StringBuilder ( );
        int i = 0;
        Set < String > set = parameterMap.keySet ( );
        List < String > list = new ArrayList < String > ( set );
        Collections.sort ( list , Collator.getInstance ( java.util.Locale.ENGLISH ) );
        for ( String key : list )
        {
            if ( ! token.equals ( key ) && ! "timeStamp".equals ( key )&&!"languageType".equals(key))
            {
                i ++ ;
                String value = request.getParameter ( key );
                if ( value != null && ! "".equals ( value ) )
                {
                    Pattern emoji = Pattern.compile ( "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]" ,
                                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE );
                    Matcher emojiMatcher = emoji.matcher ( value );
                    if ( emojiMatcher.find ( ) )
                    {
                        builder.append ( "123" );
                    }
                    else if ( value.length ( ) > 3 )
                    {
                        builder.append ( value.substring ( value.length ( ) - 3 ) );
                    }
                    else
                    {
                        builder.append ( value );
                    }
                }
            }
            if ( i == 5 )
            {
                break;
            }
        }
        return builder.toString ( );
    }
    
}
